﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using Galaktika.BI.Runtime.Services;
using Galaktika.BI.Charting;
using System.Collections.Generic;
using Ranet.AgOlap.Controls.Gauge;
using Ranet.AgOlap.Controls.General;
using Ranet.AgOlap.Controls.ContextMenu;
using Galaktika.BI.Extensibility.Dom;
using Galaktika.BI.Silverlight.Services;
using Galaktika.BI.Silverlight.Controls.PivotGrid;
using Galaktika.BI.Extensibility;
using Galaktika.BI.Extensibility.ComponentModel;

namespace Galaktika.BI.Silverlight.Controls.Gauge
{
    public class GaugeKPI : Round360Base, IEditableObject, IBindableObject
    {
        //Dial360 m_Dial;

        public GaugeKPI()
        {
            base.MouseLeftButtonUp += new MouseButtonEventHandler(GaugeKPI_MouseLeftButtonUp);
        }

        void GaugeKPI_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            this.OnMouseClick(e);
        }

        public event MouseEventHandler MouseClick;
        protected void OnMouseClick(MouseEventArgs e)
        {
            if (this.MouseClick != null)
            {
                this.MouseClick(this, e);
            }
        }

        protected override CustomContextMenu CreateContextMenu()
        {
            CustomContextMenu contextMenu = base.CreateContextMenu();
            if (contextMenu != null)
            {
                if (AContextActions != null && AContextActions.Count > 0)
                {
                    if (contextMenu.Items.Count > 0)
                    {
                        contextMenu.AddMenuSplitter();
                    }

                    foreach (ActionInfo info in AContextActions)
                    {
                        ContextMenuItem item = new ContextMenuItem(info.ACaption);
                        item.ItemClick += new EventHandler(ContextMenu_ItemClick);
                        item.Tag = info;
                        item.Icon = UriResources.Images.ActionNode16;
                        contextMenu.AddMenuItem(item);
                    }
                }

            }
            
            return contextMenu;
        }

        void ContextMenu_ItemClick(object sender, EventArgs e)
        {
            ContextMenuItem item = sender as ContextMenuItem;
            if (item != null && item.Tag != null)
            {
                if (item.Tag is ActionInfo)
                {
                    ActionInfo ai = item.Tag as ActionInfo;
                    if (ai != null && ai.AActionInvoker != null && ((BrickActionInvoker)ai.AActionInvoker).Action != null)
                    {
                        List<ArgumentEntry> args = new List<ArgumentEntry>(((BrickActionInvoker)ai.AActionInvoker).Parameters);
                        ScriptEngine.Execute(new MockCaller(this.Context), ((BrickActionInvoker)ai.AActionInvoker).Action, args);
                    }
                    return;
                }
            }   
        }

        private CustomList<ActionInfo> m_ContextActions = new CustomList<ActionInfo>();
        public CustomList<ActionInfo> AContextActions
        {
            get
            {
                return m_ContextActions;
            }
            set
            {
                m_ContextActions = value;
            }
        }

        #region Additional
        /// <summary>
        /// BadColor.
        /// </summary>
        [Browsable(false)]
        public Color ABadColor
        {
            get
            {
                return base.BadColor;
            }
            set
            {
                base.BadColor = value;
            }
        }

        /// <summary>
        /// BadColor.
        /// </summary>
        [Browsable(false)]
        public Color AMidColor
        {
            get
            {
                return base.MiddleColor;
            }
            set
            {
                base.MiddleColor = value;
            }
        }

        /// <summary>
        /// BadColor.
        /// </summary>
        [Browsable(false)]
        public Color AGoodColor
        {
            get
            {
                return base.GoodColor;
            }
            set
            {
                base.GoodColor = value;
            }
        }

        /// <summary>
        /// Улучшение показателя - это стремление к максимуму.
        /// </summary>
        [Browsable(false)]
        public bool ALowToHigh
        {
            get
            {
                return base.LowToHigh;
            }
            set
            {
                base.LowToHigh = value;
            }
        }

        [Browsable(false)]
        public Color ABackColor
        {
            get
            {
                return base.BackgroundColor;
            }
            set
            {
                base.BackgroundColor = value;
            }
        }

        [Browsable(false)]
        public double AMeterMargin
        {
            get
            {
                return base.MeterMargin;
            }
            set
            {
                base.MeterMargin = value;
            }
        }

        //[Browsable(false)]
        //public Image ABackGroundImage
        //{
        //    get
        //    {
        //        return this.BackgroundImage;
        //    }
        //    set
        //    {
        //        this.BackgroundImage = value;
        //        //requiresRedraw = true;
        //        this.Invalidate();
        //    }
        //}

        //[Browsable(false)]
        //public ImageLayout ABackgroundImageLayout
        //{
        //    get
        //    {
        //        return this.BackgroundImageLayout;
        //    }
        //    set
        //    {
        //        this.BackgroundImageLayout = value;
        //        //requiresRedraw = true;
        //        this.Invalidate();
        //    }
        //}

        //[Browsable(false)]
        //public BorderStyle ABorderStyle
        //{
        //    get
        //    {
        //        return this.BorderStyle;
        //    }
        //    set
        //    {
        //        this.BorderStyle = value;
        //        //requiresRedraw = true;
        //        this.Invalidate();
        //    }
        //}

        //[Browsable(false)]
        //public Font AFont
        //{
        //    get
        //    {
        //        return this.Font;
        //    }
        //    set
        //    {
        //        this.Font = value;
        //        //requiresRedraw = true;
        //        this.Invalidate();
        //    }
        //}

        [Browsable(false)]
        public Color AForeColor
        {
            get
            {
                return base.ForeColor;
            }
            set
            {
                base.ForeColor = value;
            }
        }

        //private bool showToolTips = true;
        //[Browsable(false)]
        //public bool AShowToolTips
        //{
        //    get
        //    {
        //        return showToolTips;
        //    }
        //    set
        //    {
        //        showToolTips = value;
        //        if (value == true)
        //            toolTip1.SetToolTip(this, AToolTipText);
        //        else
        //            toolTip1.SetToolTip(this, string.Empty);
        //    }
        //}

        [Browsable(false)]
        public string AToolTipText
        {
            get
            {
                return base.ToolTipText;
            }
            set
            {
                base.ToolTipText = value;
            }
        }

        public Cursor ACursor
        {
            get
            {
                return this.Cursor;
            }
            set
            {
                this.Cursor = value;
            }
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// Mininum value on the scale
        /// </summary>
        [Browsable(false)]
        public object AMinValue
        {
            get { return base.MinValue; }
            set
            {
                try
                {
                    base.MinValue = Convert.ToDouble(value);
                }
                catch {
                    base.MinValue = 0;
                }
                //if (value < maxValue)
                //{
                //    minValue = value;
                //    if (currentValue < minValue)
                //        currentValue = minValue;
                //    if (recommendedValue < minValue)
                //        recommendedValue = minValue;
                //    requiresRedraw = true;
                //    this.Invalidate();
                //}
            }
        }

        /// <summary>
        /// Maximum value on the scale
        /// </summary>
        [Browsable(false)]
        public object AMaxValue
        {
            get { return base.MaxValue; }
            set
            {
                try
                {
                    base.MaxValue = Convert.ToDouble(value);
                }
                catch
                {
                    base.MaxValue = 0;
                }
                //if (value > minValue)
                //{
                //    maxValue = value;
                //    if (currentValue > maxValue)
                //        currentValue = maxValue;
                //    if (recommendedValue > maxValue)
                //        recommendedValue = maxValue;
                //    requiresRedraw = true;
                //    this.Invalidate();
                //}
            }
        }

        /// <summary>
        /// Value where the pointer will point to.
        /// </summary>
        [Browsable(false)]
        public object AValue
        {
            get { return base.CurrentValue; }
            set
            {
                try
                {
                    CurrentValue = Convert.ToDouble(value);
                }
                catch
                {
                    CurrentValue = 0;
                }
                //if (value >= minValue && value <= maxValue)
                //{
                //    currentValue = value;
                //    this.Refresh();
                //}

                //if (value > maxValue)
                //{
                //    currentValue = maxValue;
                //}
                //else if (value < minValue)
                //{
                //    currentValue = minValue;
                //}
                //else
                //{
                //    currentValue = value;
                //}
                //this.Refresh();
            }
        }

        /// <summary>
        /// HiValue.
        /// </summary>
        [Browsable(false)]
        public object AHiValue
        {
            get { return base.HightValue; }
            set
            {
                //                if (value >= minValue && value <= maxValue)
                {
                    try
                    {
                        base.HightValue = Convert.ToDouble(value);
                    }
                    catch {
                        base.HightValue = double.MinValue;
                    }
                    //                   this.Refresh();
                }
            }
        }

        /// <summary>
        /// HiValue.
        /// </summary>
        [Browsable(false)]
        public object ALoValue
        {
            get { return base.LowValue; }
            set
            {
                //               if (value >= minValue && value <= maxValue)
                {
                    try
                    {
                        base.LowValue = Convert.ToDouble(value);
                    }
                    catch {
                        base.LowValue = double.MinValue;
                    }
                    //                  this.Refresh();
                }
            }
        }

        [Browsable(false)]
        public string AFormatString
        {
            get
            {
                return base.CurrentValueFormatString;
            }
            set
            {
                base.CurrentValueFormatString = value;
            }
        }

        [Browsable(false)]
        public String ADivisionsFormatString
        {
            get
            {
                return base.DivisionsFormatString;
            }
            set
            {
                base.DivisionsFormatString = value;
            }
        }

        /// <summary>
        /// Background color of the dial
        /// </summary>
        [Browsable(false)]
        public Color ADialColor
        {
            get { return base.RoundBackgroundColor; }
            set
            {
                base.RoundBackgroundColor = value;
            }
        }

        ///// <summary>
        ///// Glossiness strength. Range: 0-100
        ///// </summary>
        //[Browsable(false)]
        //public float AGlossiness
        //{
        //    get
        //    {
        //        return (glossinessAlpha * 100) / 220;
        //    }
        //    set
        //    {
        //        float val = value;
        //        if (val > 100)
        //            value = 100;
        //        if (val < 0)
        //            value = 0;
        //        glossinessAlpha = (value * 220) / 100;
        //        this.Refresh();
        //    }
        //}

        /// <summary>
        /// Get or Sets the number of Divisions in the dial scale.
        /// </summary>
        [Browsable(false)]
        public int ANoOfDivisions
        {
            get { return base.DivisionsCount; }
            set
            {
                if (value > 1 && value < 25)
                {
                    base.DivisionsCount = value;
                }
            }
        }

        /// <summary>
        /// Gets or Sets the number of Sub Divisions in the scale per Division.
        /// </summary>
        [Browsable(false)]
        public int ANoOfSubDivisions
        {
            get { return base.SubDivisionsCount; }
            set
            {
                if (value > 0 && value <= 10)
                {
                    base.SubDivisionsCount = value;
                }
            }
        }

        /// <summary>
        /// Gets or Sets the Text to be displayed in the dial
        /// </summary>
        [Browsable(false)]
        public string ADialText
        {
            get { return base.Text; }
            set
            {
                base.Text = value;
            }
        }

        //private Font m_DialTextFont;
        //[Browsable(false)]
        //public Font ADialTextFont
        //{
        //    get
        //    {
        //        //return this.Font;
        //        if (this.m_DialTextFont != null)
        //        {
        //            return this.m_DialTextFont;
        //        }
        //        return this.Font;
        //    }
        //    set
        //    {
        //        //this.Font = value;
        //        //requiresRedraw = true;

        //        this.m_DialTextFont = value;
        //        this.Invalidate();
        //    }
        //}

        ///// <summary>
        ///// Enables or Disables Transparent Background color.
        ///// Note: Enabling this will reduce the performance and may make the control flicker.
        ///// </summary>
        //[Browsable(false)]
        //public bool AEnableTransparentBackground
        //{
        //    get { return this.enableTransparentBackground; }
        //    set
        //    {
        //        this.enableTransparentBackground = value;
        //        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, !enableTransparentBackground);
        //        //requiresRedraw = true;
        //        this.Refresh();
        //    }
        //}

        [Browsable(false)]
        public bool AHidePercentageInDivisions
        {
            get
            {
                return base.HidePercentageInDivisions;
            }
            set
            {
                base.HidePercentageInDivisions = value;
            }
        }

        [Browsable(false)]
        public bool AHidePercentageInValue
        {
            get
            {
                return base.HidePercentageInValue;
            }
            set
            {
                base.HidePercentageInValue = value;
            }
        }

        #endregion

        #region IEditableObject members
        void IEditableObject.BeginEdit()
        {
        }

        void IEditableObject.CancelEdit()
        {
        }

        void IEditableObject.EndEdit()
        {
            base.Refresh();
        }
        #endregion

        #region IBindableObject Members

        private IBindingContext m_Context;
        public IBindingContext Context
        {
            get
            {
                return m_Context;
            }
            set
            {
                m_Context = value;
            }
        }

        private Dictionary<string, IBindingManager> m_Bindings;
        public IDictionary<string, IBindingManager> Bindings
        {
            get
            {
                if (m_Bindings == null)
                {
                    m_Bindings = new Dictionary<string, IBindingManager>();
                }

                return m_Bindings;
            }
        }

        #endregion
    }
}
